<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    html,body{margin: 0;padding: 0;}
  </style>
</head>
<body>
  <canvas class="cvs"></canvas>
</body>
<script>

  const cvs = document.querySelector(".cvs");
  // 设置canvas的尺寸同屏幕大小
  cvs.width = window.innerWidth;
  cvs.height = window.innerHeight;

  const c2d = cvs.getContext("2d");

  // 每次拖拽之前，形状的坐标
  let x0 = 20;
  let y0 = 20;
  // 形状的坐标和大小信息
  let x = 20;
  let y = 20;
  let w = 100;
  let h = 80;
  // 初始绘制
  drawRect(c2d, x, y, w, h);
  
  // 按下
  cvs.onmousedown = function(eve){
    const downE = eve || window.event;
    // 检测是否在要拖拽的图形内触发的事件
    if(
      downE.offsetX > x && downE.offsetX < x + w
      &&
      downE.offsetY > y && downE.offsetY < y + h
    ){
      // 移动
      cvs.onmousemove = function(eve){
        const moveE = eve || window.event;
        // 计算图形的坐标：移动时鼠标的坐标 - 按下时鼠标的坐标 + 按下时图形的坐标
        x = moveE.offsetX - downE.offsetX + x0;
        y = moveE.offsetY - downE.offsetY + y0;
        // 擦除之前的图形
        c2d.clearRect(0,0,cvs.width,cvs.height);
        // 重新绘制
        drawRect(c2d, x, y, w, h);
      }
      cvs.onmouseup = function(){
        cvs.onmousemove = cvs.onmouseup = null;
        // 抬起鼠标后，将图形最后的坐标设置成下次按下时图形的初始坐标
        x0 = x;
        y0 = y;
      }
    }
  }


  // 绘制矩形的功能封装
  function drawRect(c2d, x, y, w, h){
    c2d.beginPath();
    c2d.rect(x, y, w, h);
    c2d.stroke();
  }

  
</script>
</html>